#ifndef HASH_H
#define HASH_H

#include <stdbool.h>

/* *********************************************************************
 * 			DEFINICION DEL TIPO DE DATO
 * ********************************************************************/

typedef struct hash hash_t;

typedef struct hash_iter hash_iter_t;

typedef void (*hash_destruir_dato_t)(void *);

/* *********************************************************************
 * 				PRIMITIVAS DEL TDA
 * ********************************************************************/

// Crea un hash.
// Post: devuelve un nuevo hash vacío.
hash_t *hash_crear(hash_destruir_dato_t destruir_dato);

// guarda un valor en el hash en la posicion que le corresponda a la clave.
// pre: el hash fue creado.
// post: devuelve true o false dependiendo si lo pudo guardar.
bool hash_guardar(hash_t *hash, const char *clave, void *dato);

// elimina del hash el elemento al cual pertenece la clave pasada por
// parametro.
// pre: el hash fue creado.
// post: el valor fue eliminado del hash
void *hash_borrar(hash_t *hash, const char *clave);

// devuelve el valor al que le pertenece la clave entregada.
// pre: el hash fue creado.
// post: se devolvio el valor que corresponde, o NULL si la clave no 
// pertenece al hash.
void *hash_obtener(const hash_t *hash, const char *clave);

// infidica si elemento pertenece al hash.
// pre: el hash fue creado.
// post: se devolvio TRUE o FALSE segun pertenece.
bool hash_pertenece(const hash_t *hash, const char *clave);

// indica la cantidad de elemento almacenados en el hash.
// pre: el hash fue creado.
// post: se devolvio la cantidad de elemantos del hash.
size_t hash_cantidad(const hash_t *hash);

// se destruye el hash pasado por parametro
// pre: el hash fue creado.
// post: el hash fue detruido.
void hash_destruir(hash_t *hash);

// se crea un iterador al hash
// pre: el hash fue creado.
// post: se devuelve un iterador apuntando a el primer elemento, o a
// NULL si no los hay.
hash_iter_t *hash_iter_crear(const hash_t *hash);

// avanza el iterador al siguiente elemento si existe. 
// solo se detiene en un NULL si no hay mas elementos.
// pre: el iterador fue creado.
// post: devuelve TRUE si avanzo, y sino FALSE.
bool hash_iter_avanzar(hash_iter_t *iter);

// muestra la clave a la que apunta el iterador.
// pre: el iterador fue creado.
// post: devolvio la clave a la que apunta.
const char *hash_iter_ver_actual(const hash_iter_t *iter);

// indica si se recorrieron todos los elementos del hash.
// pre: el iterador fue creado.
// post: indica TRUE si y solo si no hay mas elementos en el hash.
bool hash_iter_al_final(const hash_iter_t *iter);

// destruye el iterador pasado por parametro.
// pre: el iterador fue creado.
// post: se destruyo el hash.
void hash_iter_destruir(hash_iter_t* iter);


#endif //HASH_H
